<?php defined('IN_LK') or die('Access Denied');
/**
 * 计算机图灵检测类
 * @author yangzhiguo0903@163.com
 * @access public
 */
class captcha
{
	/**
	 * 图像句柄
	 */
	private $image = null;	
	
	/**
	 * 图片宽
	 */
	private $width = 130;
	
	/**
	 * 图片高
	 */
	private $height = 60;
	
	/**
	 * 图像背景
	 */
	private $background = '#F7FDF0';
	
	/**
	 * 随机码个数
	 */
	private $size = 4;
		
	/**
	 * 随机码类型 
	 * 1 => 纯数字
	 * 2 => 英文
	 * 3 => 英文和数字
	 */
	private $type = 3;
	
	/**
	 * 随机码因子
	 */
	private static $code_from = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

	/**
	 * 随机码
	 */
	public $code;
	
	/**
	 * 字体文件
	 */
	private $font;
	
	/**
	 * 字体颜色
	 */
	private $fontcolor = '#6486DE';
	
	/**
	 * 初始化
	 * @param int $width      图像宽度
	 * @param int $height     图像高度
	 * @param int $background 图像背景
	 * @param int $size       验证码个数
	 * @param int $type       验证码类型
	 * @param int $fontcolor  验证码颜色
	 */
	public function __construct($width = 0, $height = 0, $background = '', $size = 0, $type = 0, $fontcolor = '')
	{
		$this->width      = $width      ? $width      : $this->width;
		$this->height     = $height     ? $height     : $this->height;
		$this->background = $background ? $background : $this->background;
		$this->size       = $size       ? $size       : $this->size;
		$this->type       = $type       ? $type       : $this->type;
		$this->fontcolor  = $fontcolor  ? $fontcolor  : $this->fontcolor;
		$this->code = $this->random($this->size);
		$this->font = APP_ROOT . 'libs' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'font' . DIRECTORY_SEPARATOR . 'elephant.ttf';
		$_SESSION['captcha'] = strtolower($this->code);
	
		$this->create_image();
		$this->create_mix();
		$this->create_font();
	}
	
	/**
	 * 生成图片及背景
	 */
	private function create_image()
	{
		$this->image = imagecreatetruecolor($this->width, $this->height);
		$background  = imagecolorallocate($this->image, 
										  hexdec(substr($this->background, 1, 2)), 
										  hexdec(substr($this->background, 3, 2)), 
										  hexdec(substr($this->background, 5, 2)));
		imagefill($this->image, 0, 0, $background);
	}
	
	/**
	 * 生成干扰图像
	 */
	private function create_mix()
	{
		$mixcolor = imagecolorallocate($this->image, mt_rand(180, 220), mt_rand(180, 220), mt_rand(180, 220));
		for($i = 0; $i <=4; $i ++)
		{
			imagesetthickness($this->image, 3);
			imagearc($this->image, 
					mt_rand(1, $this->width - 1), 
					mt_rand(1, $this->height - 1), 
					mt_rand(30, 200),
					mt_rand(30, 100), 
					mt_rand(-30, 90), 
					mt_rand(50, 100), 
					$mixcolor);
		}
	}
	
	/**
	 * 生成字符
	 */
	private function create_font()
	{
		//$color  = imagecolorallocate($this->image, 
		//								  hexdec(substr($this->fontcolor, 1, 2)), 
		//								  hexdec(substr($this->fontcolor, 3, 2)), 
		//								  hexdec(substr($this->fontcolor, 5, 2)));
		$color = imagecolorallocate($this->image, mt_rand(30, 150), mt_rand(30, 150), mt_rand(30, 150));
		$y = $this->y();
		if(!is_file($this->font))
		{
			for($i = 0; $i <$this->size; $i ++)
			{
				$x = $this->x($i);
				imagestring($this->image, 5, $x, $y, $this->code{$i}, $color);
			}
		}
		else
		{
			for($i = 0; $i <$this->size; $i ++)
			{
				$x = $this->x($i);
				imagefttext($this->image, mt_rand(12, 16), mt_rand(-30, 30), $x, $y + 18, $color, $this->font, $this->code{$i});
			}
		}
	}
	
	/**
	 * 输出图片 销毁图像句柄
	 */
	public function output()
	{
		header('Content-type:image/png');
		imagepng($this->image);
		imagedestroy($this->image);
	}
	
    /**
	 * x轴算法
	 */
	private function x($i)
	{
		return (int)$this->width/12 + (int)($this->width/$this->size) * $i;
	}
	 
    /**
	 * y轴算法
	 */
	private function y()
	{
		return (int)$this->height/2 - 9;
	}
	
    /**
	 * 生成随机数
	 * @param  int    $size 随机码个数
	 * @return string 
	 */
	private function random($size = 4)
	{
		$t = '';
		switch($this->type)
		{
			case 1:
				$min = 0;
				$max = 9;
				break;
			case 2:
				$min = 10;
				$max = 61;
			case 3:
			default:
				$min = 0;
				$max = 61;
		}
		for($i = 1; $i <=$size; $i ++)
		{
			$pos = mt_rand($min, $max);
			$t .= self::$code_from{$pos};
		}
		return $t;
	}
}